`timescale 1ns/1ps
`default_nettype none

module led_display_config (
    // system signal
    input  wire         I_sclk,  // 125M
    input  wire         I_rst_n,
    // bus interface
    input  wire         I_bus_init_done,
    input  wire         I_bus_write,
    input  wire         I_bus_read,
    input  wire [15:0]  I_bus_addr,
    input  wire [7:0]   I_bus_wdata,
    output wire [7:0]   O_bus_rdata,
    // registers
    // 0x1000: 大屏连接
    output reg  [12:0]  O_cfg_win_pos_x,        // x坐标，有符号
    output reg  [11:0]  O_cfg_win_pos_y,        // y坐标，有符号
    output reg  [10:0]  O_cfg_win_col_num,      // 带载列数（宽度）
    output reg  [10:0]  O_cfg_win_row_num,      // 带载行数（高度）
    output reg  [7:0]   O_cfg_win_id,           // 屏幕id
    // 0x2000: 箱体设置
    output reg  [5:0]   O_cfg_color_sel,        // RGB选择
    output reg  [2:0]   O_cfg_decode_type,      // 译码方式
    output reg          O_cfg_data_polarity,    // 数据极性
    output reg          O_cfg_oe_polarity,      // oe极性
    output reg  [9:0]   O_cfg_scan_pixel,       // 一扫的像素数量（不包含虚点）
    output reg  [9:0]   O_cfg_scan_length,      // 一扫的像素数量（包含虚点）
    output reg  [5:0]   O_cfg_scan_max,         // 最大扫描id
    output reg  [4:0]   O_cfg_port_max,         // 最大端口id
    output reg  [3:0]   O_cfg_sector_count,     // 多开数量
    output reg  [10:0]  O_cfg_sector_width,     // 每个"多开区域"宽度
    output reg  [9:0]   O_cfg_sector_height,    // 每个"多开区域"高度
    output reg  [1:0]   O_cfg_scan_mode,
    output reg  [7:0]   O_cfg_chip_type,        // 芯片类型
    output reg  [1:0]   O_cfg_box_dir,          // 箱体方向
    output reg  [1:0]   O_cfg_block_max,        // 列模式下最大分区id
    output reg  [1:0]   O_cfg_col_loop,         // 列模式读取循环次数(数据组数/8,向上取整)
    output reg  [7:0]   O_cfg_col_step,         // 列模式每次读地址间隔
    output reg  [7:0]   O_cfg_vport_num,        // 虚拟数据组数
    output reg  [31:0]  O_cfg_vport_mask,       // 虚拟数据组中有效组标识
    output reg  [15:0]  O_cfg_decode_param0,    // 译码参数0
    output reg  [15:0]  O_cfg_decode_param1,    // 译码参数1
    output reg  [15:0]  O_cfg_deghost_ctrl_dly, // 译码参数0
    output reg  [15:0]  O_cfg_deghost_ctrl_len, // 译码参数1
    output reg  [7:0]   O_cfg_port_height,      // 每个port带载高度
    output reg  [3:0]   O_cfg_hub_brd_type,     // 0:HUB320_4_JACK; 1:HUB75E_8_JACK; 2:HUB75E_10_JACK; ...
    // 0x3000: 端口映射
    // 0x4000: 列映射
    // 0x5000: 行映射
    // 0x6000: 显示效果
    output reg  [7:0]   O_cfg_clock_low,      // 时钟低电平时钟数
    output reg  [7:0]   O_cfg_clock_cycle,    // 时钟整周期时钟数
    output reg  [7:0]   O_cfg_clock_phase,    // 时钟相位
    output reg  [7:0]   O_cfg_clock_phase_2,  // 时钟相位2
    output reg  [7:0]   O_cfg_line_pos,       // 换行位置
    output reg  [7:0]   O_cfg_load_width,     // load信号宽度 (>=2)
    output reg  [7:0]   O_cfg_oe_pre_width,   // 切换非整周期时oe提前拉低宽度
    output reg  [15:0]  O_cfg_chain_cycle,    // 串移时钟数
    output reg          O_cfg_fps_sync_en,    // 帧率同步使能
    output reg  [15:0]  O_cfg_min_chain,      // 最小串移周期数
    output reg  [11:0]  O_cfg_chain_num,      // 显示周期串移数
    // 0x7000: GAMMA表
    output reg          O_cfg_color_restore,  // 色彩还原
    output reg  [3:0]   O_cfg_gamma_bit,      // gamma bit数, 0 - 1bit, ..., 15 - 16bit
    output reg          O_cfg_gamma_incr,     // 低灰递增补偿
    // 0x8000: 箱体调整
    output reg          O_cfg_temp_adj_en,    // 全局色温调整
    output reg          O_cfg_color_adj_en,   // 全局色度调整
    output reg  [15:0]  O_cfg_temp_coe_r,     // 色温调整系数
    output reg  [15:0]  O_cfg_temp_coe_g,     // 色温调整系数
    output reg  [15:0]  O_cfg_temp_coe_b,     // 色温调整系数
    output reg  [15:0]  O_cfg_color_coe_r0,   // 全局色度调整系数
    output reg  [15:0]  O_cfg_color_coe_g0,   // 全局色度调整系数
    output reg  [15:0]  O_cfg_color_coe_b0,   // 全局色度调整系数
    output reg  [15:0]  O_cfg_color_coe_r1,   // 全局色度调整系数
    output reg  [15:0]  O_cfg_color_coe_g1,   // 全局色度调整系数
    output reg  [15:0]  O_cfg_color_coe_b1,   // 全局色度调整系数
    output reg  [15:0]  O_cfg_color_coe_r2,   // 全局色度调整系数
    output reg  [15:0]  O_cfg_color_coe_g2,   // 全局色度调整系数
    output reg  [15:0]  O_cfg_color_coe_b2,   // 全局色度调整系数
    output reg          O_cfg_black_on_lost,  // 丢失信号后黑屏
    // 0x9000: 逐点调整
    output reg          O_cfg_pixel_adj_en,   // 逐点色度调整
    output reg          O_cfg_pixel_adj_mode, // 逐点色度调整
    // 0xa000: 特殊芯片设置
    output reg  [255:0] O_cfg_pwm_setting,    // pwm芯片设置
    // 0x0000: 缝隙设置
    output reg          O_cfg_gap_adj_en,     // 缝隙调整使能
    output reg  [7:0]   O_cfg_module_width,   // 模组宽度
    output reg  [7:0]   O_cfg_module_height,  // 模组高度
    output reg  [5:0]   O_cfg_module_col,     // 模组列数
    output reg  [15:0]  O_cfg_gap_center,     // 模组中间调整系数
    // 0xf000: 临时设置
    output reg          O_cfg_input_enable,   // 输入使能
    output reg          O_cfg_output_enable,  // 输出使能
    output reg  [3:0]   O_cfg_pattern_mode,   // pattern工作模式
    output reg  [2:0]   O_cfg_pattern_rgb,    // pattern颜色
    output reg  [7:0]   O_cfg_pattern_col,    // pattern当前列
    output reg  [7:0]   O_cfg_pattern_row,    // pattern当前行
    output reg  [7:0]   O_cfg_pattern_pos_x,  // pattern走行时x坐标
    output reg  [10:0]  O_cfg_pattern_width,  // pattern宽度
    output reg  [10:0]  O_cfg_pattern_height, // pattern高度
    output reg  [10:0]  O_cfg_pattern_hblank, // pattern行间隔时间
    output reg  [10:0]  O_cfg_pattern_vblank, // pattern列间隔
    output reg          O_cfg_force_en,       // 强制读出的第几bit为1，其余bit为0
    output reg  [4:0]   O_cfg_force_bit,      // 0:全为0; 1:只bit0为1; 2:只bit1为1; ...
    // gamma table
    input  wire         I_gamma_start, // 为1时表示红色分量，接下来2周期分别为绿蓝分量
    input  wire [7:0]   I_gamma_data,
    output wire [15:0]  O_gamma_result,
    // gap info
    input  wire         I_gap_coe_req,
    input  wire [9:0]   I_gap_coe_row,
    output wire         O_gap_coe_busy,
    input  wire         I_gap_coe_ack,
    output wire [15:0]  O_gap_coe_val,
    // rgb row addr decoder
    input  wire         I_rgb_decode_req,     // 行地址译码请求
    input  wire [1:0]   I_rgb_decode_buf_sel, // SDRAM按帧分块选择
    input  wire [9:0]   I_rgb_decode_row,     // 行号
    input  wire [3:0]   I_rgb_decode_sector,  // 分区号
    output wire         O_rgb_decode_done,    // 译码完成
    output wire [20:0]  O_rgb_decode_addr,    // 译码结果
    
    output wire [9:0]   O_rgb_decode_col_addr,
    input  wire [9:0]   I_rgb_decode_col_addr,
    
    
    // cycle info
    input  wire         I_cycle_info_rden,
    input  wire [8:0]   I_cycle_info_addr,
    output wire [15:0]  O_cycle_info_q,
    // scan map
    input  wire         I_scan_map_rden,
    input  wire [5:0]   I_scan_map_addr,
    output wire [5:0]   O_scan_map_q,
    // port map
    input  wire         I_port_map_rden,
    input  wire [7:0]   I_port_map_addr,
    output wire [4:0]   O_port_map_q,
    // port map 2
    input  wire         I_port_map_rden_2,
    input  wire [7:0]   I_port_map_addr_2,
    output wire [15:0]  O_port_map_q_2,
    // column info
    input  wire         I_col_addr_req,
    input  wire [8:0]   I_col_addr_index,
    output wire [8:0]   O_col_addr_data
);
//------------------------Parameter----------------------

//------------------------Local signal-------------------
// registers
reg         O_cfg_gamma_enable; // 使用前缀O_便于设置伪路径
reg         init_done_sr;

// ram0
wire        ram0_wren;
wire        ram0_rden;
wire [9:0]  ram0_waddr;
wire [7:0]  ram0_raddr;
wire [7:0]  ram0_data;
wire [31:0] ram0_q;

// ram1
wire        ram1_wren;
wire        ram1_rden;
wire [9:0]  ram1_waddr;
wire [8:0]  ram1_raddr;
wire [7:0]  ram1_data;
wire [15:0] ram1_q;

// ram2
wire        ram2_wren;
wire        ram2_rden;
wire [9:0]  ram2_waddr;
wire [8:0]  ram2_raddr;
wire [7:0]  ram2_data;
wire [15:0] ram2_q;

// ram3
wire        ram3_wren_a;
wire        ram3_rden_a;
wire [1:0]  ram3_be_a;
wire [8:0]  ram3_addr_a;
wire [15:0] ram3_data_a;
wire [15:0] ram3_q_a;
wire        ram3_wren_b;
wire        ram3_rden_b;
wire [8:0]  ram3_addr_b;
wire [15:0] ram3_data_b;
wire [15:0] ram3_q_b;

// ram4
wire        ram4_wren;
wire [9:0]  ram4_waddr;
wire [7:0]  ram4_data;
wire        ram4_rden;
wire [9:0]  ram4_raddr;
wire [7:0]  ram4_q;

// ram4_2
wire        ram4_wren_2;
wire [9:0]  ram4_waddr_2;
wire [7:0]  ram4_data_2;
wire        ram4_rden_2;
wire [8:0]  ram4_raddr_2;
wire [15:0] ram4_q_2;

// ram5
wire        ram5_wren;
wire        ram5_rden;
wire [9:0]  ram5_waddr;
wire [8:0]  ram5_raddr;
wire [7:0]  ram5_data;
wire [15:0] ram5_q;

// row info
wire        row_info_req;
wire [7:0]  row_info_index;
wire [15:0] row_info_data;

//------------------------Instantiation------------------
// sdpram_1024x8_256x32 (for gamma table)
sdpram_1024x8_256x32 ram0 (/*{{{*/
    .clock     ( I_sclk ),
    .data      ( ram0_data ),
    .rdaddress ( ram0_raddr ),
    .rden      ( ram0_rden ),
    .wraddress ( ram0_waddr ),
    .wren      ( ram0_wren ),
    .q         ( ram0_q )
);/*}}}*/


// sdpram_lpm #(
    // .A_ADDRESS_WIDTH    (   10  ),
    // .A_DATA_WIDTH       (   8   ),
    // .B_ADDRESS_WIDTH    (   8   ),
    // .B_DATA_WIDTH       (   32  )
    // )
// ram0(
    // .clka       (   I_sclk      ),
    // .wea        (   ram0_wren    ),
    // .addra      (   ram0_waddr   ),
    // .dina       (   ram0_data    ),

    // .clkb       (   I_sclk      ),
    // .reb        (   ram0_rden    ),
    // .addrb      (   ram0_raddr   ),
    // .doutb      (   ram0_q       )
    
// );

// sdpram_1024x8_512x16 (for cycle info)
sdpram_1024x8_512x16 ram1 (/*{{{*/
    .wrclock   ( I_sclk ),
    .rdclock   ( I_sclk ),
    .data      ( ram1_data ),
    .rdaddress ( ram1_raddr ),
    .rden      ( ram1_rden ),
    .wraddress ( ram1_waddr ),
    .wren      ( ram1_wren ),
    .q         ( ram1_q )
);/*}}}*/

// sdpram_lpm #(
    // .A_ADDRESS_WIDTH    (   10  ),
    // .A_DATA_WIDTH       (   8   ),
    // .B_ADDRESS_WIDTH    (   9   ),
    // .B_DATA_WIDTH       (   16  )
    // )
// ram1(
    // .clka       (   I_sclk      ),
    // .wea        (   ram1_wren    ),
    // .addra      (   ram1_waddr   ),
    // .dina       (   ram1_data    ),

    // .clkb       (   I_sclk      ),
    // .reb        (   ram1_rden    ),
    // .addrb      (   ram1_raddr   ),
    // .doutb      (   ram1_q       )
    
// );

// sdpram_1024x8_512x16 (for column addr)
sdpram_1024x8_512x16 ram2 (/*{{{*/
    .wrclock   ( I_sclk ),
    .rdclock   ( I_sclk ),
    .data      ( ram2_data ),
    .rdaddress ( ram2_raddr ),
    .rden      ( ram2_rden ),
    .wraddress ( ram2_waddr ),
    .wren      ( ram2_wren ),
    .q         ( ram2_q )
);/*}}}*/

// sdpram_lpm #(
    // .A_ADDRESS_WIDTH    (   10  ),
    // .A_DATA_WIDTH       (   8   ),
    // .B_ADDRESS_WIDTH    (   9   ),
    // .B_DATA_WIDTH       (   16  )
    // )
// ram2(
    // .clka       (   I_sclk      ),
    // .wea        (   ram2_wren    ),
    // .addra      (   ram2_waddr   ),
    // .dina       (   ram2_data    ),

    // .clkb       (   I_sclk      ),
    // .reb        (   ram2_rden    ),
    // .addrb      (   ram2_raddr   ),
    // .doutb      (   ram2_q       )
    
// );

// tdpram_512x16 (for row info and scan map)
tdpram_512x16 ram3 (/*{{{*/
    .address_a ( ram3_addr_a ),
    .address_b ( ram3_addr_b ),
    .byteena_a ( ram3_be_a ),
    .clock     ( I_sclk ),
    .data_a    ( ram3_data_a ),
    .data_b    ( ram3_data_b ),
    .rden_a    ( ram3_rden_a ),
    .rden_b    ( ram3_rden_b ),
    .wren_a    ( ram3_wren_a ),
    .wren_b    ( ram3_wren_b ),
    .q_a       ( ram3_q_a ),
    .q_b       ( ram3_q_b )
);/*}}}*/

// tdpram_lpm #( 
    // .A_ADDRESS_WIDTH    (   9  ),
    // .A_DATA_WIDTH       (   16   ),
    // .A_BYTEENA_WIDTH    (   2    ),
    // .B_ADDRESS_WIDTH    (   9   ),
    // .B_DATA_WIDTH       (   16  )
// )
// ram3 (/*{{{*/
    // .addra ( ram3_addr_a ),
    // .addrb ( ram3_addr_b ),
    // .byteena_a ( ram3_be_a ),
    // .clka     ( I_sclk ),
    // .clkb     ( I_sclk ),
    // .dina    ( ram3_data_a ),
    // .dinb    ( ram3_data_b ),
    // .rea    ( ram3_rden_a ),
    // .reb    ( ram3_rden_b ),
    // .wea    ( ram3_wren_a ),
    // .web    ( ram3_wren_b ),
    // .douta       ( ram3_q_a ),
    // .doutb       ( ram3_q_b )
// );



// sdpram_1024x8 (for port map)
sdpram_1024x8 ram4 (/*{{{*/
    .clock     ( I_sclk ),
    .data      ( ram4_data ),
    .rdaddress ( ram4_raddr ),
    .rden      ( ram4_rden ),
    .wraddress ( ram4_waddr ),
    .wren      ( ram4_wren ),
    .q         ( ram4_q )
);/*}}}*/

// sdpram_lpm #(
    // .A_ADDRESS_WIDTH    (   10  ),
    // .A_DATA_WIDTH       (   8   ),
    // .B_ADDRESS_WIDTH    (   10  ),
    // .B_DATA_WIDTH       (   8   )
    // )
// ram4(
    // .clka       (   I_sclk      ),
    // .wea        (   ram4_wren   ),
    // .addra      (   ram4_waddr  ),
    // .dina       (   ram4_data   ),

    // .clkb       (   I_sclk      ),
    // .reb        (   ram4_rden   ),
    // .addrb      (   ram4_raddr  ),
    // .doutb      (   ram4_q      )
    
// );


// sdpram_1024x8_512x16 (for port map & offset)
sdpram_1024x8_512x16 ram4_2 (/*{{{*/
    .wrclock   ( I_sclk ),
    .rdclock   ( I_sclk ),
    .data      ( ram4_data_2 ),
    .rdaddress ( ram4_raddr_2 ),
    .rden      ( ram4_rden_2 ),
    .wraddress ( ram4_waddr_2 ),
    .wren      ( ram4_wren_2 ),
    .q         ( ram4_q_2 )
);/*}}}*/

// sdpram_lpm #(
    // .A_ADDRESS_WIDTH    (   10  ),
    // .A_DATA_WIDTH       (   8   ),
    // .B_ADDRESS_WIDTH    (   9   ),
    // .B_DATA_WIDTH       (   16  )
    // )
// ram4_2(
    // .clka       (   I_sclk          ),
    // .wea        (   ram4_wren_2     ),
    // .addra      (   ram4_waddr_2    ),
    // .dina       (   ram4_data_2     ),

    // .clkb       (   I_sclk          ),
    // .reb        (   ram4_rden_2     ),
    // .addrb      (   ram4_raddr_2    ),
    // .doutb      (   ram4_q_2        )
    
// );

// sdpram_1024x8_512x16 (for gap info)
sdpram_1024x8_512x16 ram5 (/*{{{*/
    .wrclock   ( I_sclk ),
    .rdclock   ( I_sclk ),
    .data      ( ram5_data ),
    .rdaddress ( ram5_raddr ),
    .rden      ( ram5_rden ),
    .wraddress ( ram5_waddr ),
    .wren      ( ram5_wren ),
    .q         ( ram5_q )
);/*}}}*/

// sdpram_lpm #(
    // .A_ADDRESS_WIDTH    (   10  ),
    // .A_DATA_WIDTH       (   8   ),
    // .B_ADDRESS_WIDTH    (   9   ),
    // .B_DATA_WIDTH       (   16  )
    // )
// ram5(
    // .clka       (   I_sclk      ),
    // .wea        (   ram5_wren    ),
    // .addra      (   ram5_waddr   ),
    // .dina       (   ram5_data    ),

    // .clkb       (   I_sclk      ),
    // .reb        (   ram5_rden    ),
    // .addrb      (   ram5_raddr   ),
    // .doutb      (   ram5_q       )
    
// );


// gap_coe_reader
gap_coe_reader gap (/*{{{*/
    .I_sclk              ( I_sclk ),
    .I_rst_n             ( I_rst_n ),
    .I_cfg_module_width  ( O_cfg_module_width ),
    .I_cfg_module_height ( O_cfg_module_height ),
    .I_cfg_module_col    ( O_cfg_module_col ),
    .I_cfg_gap_center    ( O_cfg_gap_center ),
    .I_cfg_win_col_num   ( O_cfg_win_col_num ),
    .I_cfg_sector_width  ( O_cfg_sector_width ),
    .I_cfg_box_dir       ( O_cfg_box_dir ),
    .I_cfg_col_loop      ( O_cfg_col_loop ),
    .I_cfg_col_step      ( O_cfg_col_step ),
    .O_gap_ram_rden      ( ram5_rden ),
    .O_gap_ram_addr      ( ram5_raddr ),
    .I_gap_ram_q         ( ram5_q ),
    .I_gap_coe_req       ( I_gap_coe_req ),
    .I_gap_coe_row       ( I_gap_coe_row ),
    .O_gap_coe_busy      ( O_gap_coe_busy ),
    .I_gap_coe_ack       ( I_gap_coe_ack ),
    .O_gap_coe_val       ( O_gap_coe_val )
);/*}}}*/
wire rgb_row_info_req;
reg rgb_row_info_end;
always@(posedge I_sclk)begin
    rgb_row_info_end <= rgb_row_info_req;
end

reg [9:0]decode_col_addr_out;
always@( posedge I_sclk)
    decode_col_addr_out <= I_rgb_decode_col_addr;
assign O_rgb_decode_col_addr = decode_col_addr_out[9:0] ;

wire [9:0]rgb_row_info_index;
rgb_row_addr_decoder rgb_row_addr_decoder (
    // system signal
    .I_sclk( I_sclk ),  // 125M
    .I_rst_n( I_rst_n ),
    .I_cfg_win_col_num  (O_cfg_win_col_num),      // 带载列数（宽度）
    .I_cfg_win_row_num  (O_cfg_win_row_num),      // 带载行数（高度）
    // row info
    .O_row_info_req( rgb_row_info_req ),
    .O_row_info_index( rgb_row_info_index ),
    .I_row_info_data( {6'b0,rgb_row_info_index} ),
    .I_row_info_end( rgb_row_info_end ),
    
    // addr decoder
    .I_decode_req( I_rgb_decode_req ),     // 行地址译码请求
    .I_decode_buf_sel( I_rgb_decode_buf_sel ), // SDRAM按帧分块选择
    .I_decode_row( I_rgb_decode_row ),     // 行号
    .I_decode_sector( I_rgb_decode_sector ),  // 分区号
    .O_decode_done( O_rgb_decode_done ),    // 译码完成
    .O_decode_addr( O_rgb_decode_addr )     // 译码结果
);

// gamma_table
gamma_table gamma (/*{{{*/
    .I_sclk              ( I_sclk ),
    .I_rst_n             ( I_rst_n ),
    .I_cfg_gamma_enable  ( O_cfg_gamma_enable ),
    .I_cfg_color_restore ( O_cfg_color_restore ),
    .I_cfg_gamma_bit     ( O_cfg_gamma_bit ),
    .I_cfg_gamma_incr    ( O_cfg_gamma_incr ),
    .O_gamma_ram_rden    ( ram0_rden ),
    .O_gamma_ram_addr    ( ram0_raddr ),
    .I_gamma_ram_q       ( ram0_q ),
    .I_pixel_start       ( I_gamma_start ),
    .I_pixel_grey        ( I_gamma_data ),
    .O_pixel_gamma       ( O_gamma_result )
);/*}}}*/

//------------------------Body---------------------------
//{{{+++++++++++++++++++++registers++++++++++++++++++++++
always @(*) begin
    O_cfg_color_adj_en   = 1'b0;
    O_cfg_color_coe_r0   = 1'b0;
    O_cfg_color_coe_g0   = 1'b0;
    O_cfg_color_coe_b0   = 1'b0;
    O_cfg_color_coe_r1   = 1'b0;
    O_cfg_color_coe_g1   = 1'b0;
    O_cfg_color_coe_b1   = 1'b0;
    O_cfg_color_coe_r2   = 1'b0;
    O_cfg_color_coe_g2   = 1'b0;
    O_cfg_color_coe_b2   = 1'b0;
end

always @(posedge I_sclk or negedge I_rst_n) begin
    if (~I_rst_n) begin
        O_cfg_win_pos_x         <= 1'b0;
        O_cfg_win_pos_y         <= 1'b0;
        O_cfg_win_col_num       <= 1'b0;
        O_cfg_win_row_num       <= 1'b0;
        O_cfg_win_id            <= 1'b0;
        O_cfg_color_sel         <= 1'b0;
        O_cfg_decode_type       <= 1'b0;
        O_cfg_data_polarity     <= 1'b0;
        O_cfg_oe_polarity       <= 1'b0;
        O_cfg_scan_pixel        <= 1'b0;
        O_cfg_scan_length       <= 1'b0;
        O_cfg_scan_max          <= 1'b0;
        O_cfg_port_max          <= 1'b0;
        O_cfg_sector_count      <= 1'b0;
        O_cfg_sector_width      <= 1'b0;
        O_cfg_sector_height     <= 1'b0;
        O_cfg_scan_mode         <= 1'b0;
        O_cfg_chip_type         <= 1'b0;
        O_cfg_box_dir           <= 1'b0;
        O_cfg_block_max         <= 1'b0;
        O_cfg_col_loop          <= 1'b0;
        O_cfg_col_step          <= 1'b0;
        O_cfg_vport_num         <= 1'b0;
        O_cfg_vport_mask        <= 1'b0;
        O_cfg_decode_param0     <= 1'b0;
        O_cfg_decode_param1     <= 1'b0;
        O_cfg_deghost_ctrl_dly  <= 1'b0;
        O_cfg_deghost_ctrl_len  <= 1'b0;
        O_cfg_hub_brd_type      <= 1'b0;
        O_cfg_port_height       <= 1'b0;
        O_cfg_clock_low         <= 1'b0;
        O_cfg_clock_cycle       <= 1'b0;
        O_cfg_clock_phase       <= 1'b0;
        O_cfg_clock_phase_2     <= 1'b0;
        O_cfg_line_pos          <= 1'b0;
        O_cfg_load_width        <= 1'b0;
        O_cfg_oe_pre_width      <= 1'b0;
        O_cfg_chain_cycle       <= 1'b0;
        O_cfg_fps_sync_en       <= 1'b0;
        O_cfg_min_chain         <= 1'b0;
        O_cfg_chain_num         <= 1'b0;
        O_cfg_color_restore     <= 1'b0;
        O_cfg_gamma_bit         <= 1'b0;
        O_cfg_gamma_incr        <= 1'b0;
        O_cfg_temp_adj_en       <= 1'b0;
        //O_cfg_color_adj_en    <= 1'b0;
        O_cfg_temp_coe_r        <= 1'b0;
        O_cfg_temp_coe_g        <= 1'b0;
        O_cfg_temp_coe_b        <= 1'b0;
        //O_cfg_color_coe_r0    <= 1'b0;
        //O_cfg_color_coe_g0    <= 1'b0;
        //O_cfg_color_coe_b0    <= 1'b0;
        //O_cfg_color_coe_r1    <= 1'b0;
        //O_cfg_color_coe_g1    <= 1'b0;
        //O_cfg_color_coe_b1    <= 1'b0;
        //O_cfg_color_coe_r2    <= 1'b0;
        //O_cfg_color_coe_g2    <= 1'b0;
        //O_cfg_color_coe_b2    <= 1'b0;
        O_cfg_black_on_lost     <= 1'b0;
        O_cfg_pixel_adj_en      <= 1'b0;
        O_cfg_pixel_adj_mode    <= 1'b0;
        O_cfg_gap_adj_en        <= 1'b0;
        O_cfg_module_width      <= 1'b0;
        O_cfg_module_height     <= 1'b0;
        O_cfg_module_col        <= 1'b0;
        O_cfg_gap_center        <= 1'b0;
        O_cfg_pwm_setting       <= 1'b0;
        O_cfg_pattern_mode      <= 1'b0;
        O_cfg_pattern_rgb       <= 1'b0;
        O_cfg_pattern_col       <= 1'b0;
        O_cfg_pattern_row       <= 1'b0;
        O_cfg_pattern_pos_x     <= 1'b0;
        O_cfg_pattern_width     <= 11'd1024;
        O_cfg_pattern_height    <= 11'd32;
        O_cfg_pattern_hblank    <= 11'd100;
        O_cfg_pattern_vblank    <= 11'd2000;
        O_cfg_force_en          <= 1'b0;
        O_cfg_force_bit         <= 5'b0;
        O_cfg_gamma_enable      <= 1'b1;
    end
    else if (I_bus_write && I_bus_addr[15:8] == 8'h10) begin
        case (I_bus_addr[7:0])
            8'h00 : O_cfg_win_pos_x[7:0]     <= I_bus_wdata[7:0];
            8'h01 : O_cfg_win_pos_x[12:8]    <= I_bus_wdata[4:0];
            8'h02 : O_cfg_win_pos_y[7:0]     <= I_bus_wdata[7:0];
            8'h03 : O_cfg_win_pos_y[11:8]    <= I_bus_wdata[3:0];
            8'h04 : O_cfg_win_col_num[7:0]   <= I_bus_wdata[7:0];
            8'h05 : O_cfg_win_col_num[10:8]  <= I_bus_wdata[2:0];
            8'h06 : O_cfg_win_row_num[7:0]   <= I_bus_wdata[7:0];
            8'h07 : O_cfg_win_row_num[10:8]  <= I_bus_wdata[2:0];
            8'h08 : O_cfg_win_id[7:0]        <= I_bus_wdata[7:0];
        endcase
    end
    else if (I_bus_write && I_bus_addr[15:8] == 8'h20) begin
        case (I_bus_addr[7:0])
            8'h00 : O_cfg_color_sel[5:0]         <= I_bus_wdata[5:0];
            8'h01 : O_cfg_decode_type[2:0]       <= I_bus_wdata[2:0];
            8'h02 : O_cfg_data_polarity          <= I_bus_wdata[0];
            8'h03 : O_cfg_oe_polarity            <= I_bus_wdata[0];
            8'h04 : O_cfg_scan_pixel[7:0]        <= I_bus_wdata[7:0];
            8'h05 : O_cfg_scan_pixel[9:8]        <= I_bus_wdata[1:0];
            8'h06 : O_cfg_scan_length[7:0]       <= I_bus_wdata[7:0];
            8'h07 : O_cfg_scan_length[9:8]       <= I_bus_wdata[1:0];
            8'h08 : O_cfg_scan_max[5:0]          <= I_bus_wdata[5:0];

          //8'h09 : O_cfg_port_max[4:0]          <= I_bus_wdata[4:0];  // for logic mux
            8'h24 : O_cfg_port_max[4:0]          <= I_bus_wdata[4:0];  // for port ram

            8'h0a : O_cfg_sector_count[3:0]      <= I_bus_wdata[3:0];
            8'h0b : O_cfg_sector_width[7:0]      <= I_bus_wdata[7:0];
            8'h0c : O_cfg_sector_width[10:8]     <= I_bus_wdata[2:0];
            8'h0d : O_cfg_sector_height[7:0]     <= I_bus_wdata[7:0];
            8'h0e : O_cfg_sector_height[9:8]     <= I_bus_wdata[1:0];
            8'h0f : O_cfg_scan_mode              <= I_bus_wdata[1:0];
            8'h10 : O_cfg_chip_type              <= I_bus_wdata[7:0];
            8'h11 : begin
                O_cfg_box_dir                    <= I_bus_wdata[1:0];
                O_cfg_block_max                  <= I_bus_wdata[4:3];
                O_cfg_col_loop                   <= I_bus_wdata[6:5];
            end
            8'h12 : O_cfg_col_step               <= I_bus_wdata[7:0];
            8'h13 : O_cfg_vport_num              <= I_bus_wdata[7:0];
            8'h14 : O_cfg_vport_mask[7:0]        <= I_bus_wdata[7:0];
            8'h15 : O_cfg_vport_mask[15:8]       <= I_bus_wdata[7:0];
            8'h16 : O_cfg_vport_mask[23:16]      <= I_bus_wdata[7:0];
            8'h17 : O_cfg_vport_mask[31:24]      <= I_bus_wdata[7:0];
            // 0x18~0x1f被占用
            8'h20 : O_cfg_decode_param0[7:0]     <= I_bus_wdata[7:0];
            8'h21 : O_cfg_decode_param0[15:8]    <= I_bus_wdata[7:0];
            8'h22 : O_cfg_decode_param1[7:0]     <= I_bus_wdata[7:0];
            8'h23 : O_cfg_decode_param1[15:8]    <= I_bus_wdata[7:0];
            // 0x24被"32组线时的最大端口id"占用
            8'h25 : O_cfg_deghost_ctrl_dly[7:0]  <= I_bus_wdata[7:0];
            8'h26 : O_cfg_deghost_ctrl_dly[15:8] <= I_bus_wdata[7:0];
            8'h27 : O_cfg_deghost_ctrl_len[7:0]  <= I_bus_wdata[7:0];
            8'h28 : O_cfg_deghost_ctrl_len[15:8] <= I_bus_wdata[7:0];
            8'h29 : O_cfg_hub_brd_type           <= I_bus_wdata[3:0];
            8'h2a : O_cfg_port_height            <= I_bus_wdata[7:0];
        endcase
    end
    else if (I_bus_write && I_bus_addr[15:8] == 8'h60) begin
        case (I_bus_addr[7:0])
            8'h00 : O_cfg_clock_low[7:0]     <= I_bus_wdata[7:0];
            8'h01 : O_cfg_clock_cycle[7:0]   <= I_bus_wdata[7:0];

            8'h02 : O_cfg_clock_phase[7:0]   <= I_bus_wdata[7:0];   // for no 374
            8'h15 : O_cfg_clock_phase_2[7:0] <= I_bus_wdata[7:0];   // for with 374

            8'h03 : O_cfg_line_pos[7:0]      <= I_bus_wdata[7:0];
            8'h04 : O_cfg_load_width[7:0]    <= I_bus_wdata[7:0];
            8'h05 : O_cfg_oe_pre_width[7:0]  <= I_bus_wdata[7:0];
            8'h06 : O_cfg_chain_cycle[7:0]   <= I_bus_wdata[7:0];
            8'h07 : O_cfg_chain_cycle[15:8]  <= I_bus_wdata[7:0];
            8'h08 : O_cfg_fps_sync_en        <= I_bus_wdata[0];
            8'h09 : O_cfg_min_chain[7:0]     <= I_bus_wdata[7:0];
            8'h0a : O_cfg_min_chain[15:8]    <= I_bus_wdata[7:0];
            8'h0b : O_cfg_chain_num[7:0]     <= I_bus_wdata[7:0];
            8'h0c : O_cfg_chain_num[11:8]    <= I_bus_wdata[3:0];
        endcase
    end
    else if (I_bus_write && I_bus_addr[15:8] == 8'h74) begin
        case (I_bus_addr[7:0])
            8'h00 : O_cfg_color_restore      <= I_bus_wdata[0];
            8'h01 : O_cfg_gamma_bit          <= I_bus_wdata[3:0];
            8'h02 : O_cfg_gamma_incr         <= I_bus_wdata[0];
        endcase
    end
    else if (I_bus_write && I_bus_addr[15:8] == 8'h80) begin
        case (I_bus_addr[7:0])
            8'h00 : O_cfg_temp_adj_en        <= I_bus_wdata[0];
            //8'h01 : O_cfg_color_adj_en       <= I_bus_wdata[0];
            8'h02 : O_cfg_temp_coe_r[7:0]    <= I_bus_wdata[7:0];
            8'h03 : O_cfg_temp_coe_r[15:8]   <= I_bus_wdata[7:0];
            8'h04 : O_cfg_temp_coe_g[7:0]    <= I_bus_wdata[7:0];
            8'h05 : O_cfg_temp_coe_g[15:8]   <= I_bus_wdata[7:0];
            8'h06 : O_cfg_temp_coe_b[7:0]    <= I_bus_wdata[7:0];
            8'h07 : O_cfg_temp_coe_b[15:8]   <= I_bus_wdata[7:0];
            //8'h08 : O_cfg_color_coe_r0[7:0]  <= I_bus_wdata[7:0];
            //8'h09 : O_cfg_color_coe_r0[15:8] <= I_bus_wdata[7:0];
            //8'h0a : O_cfg_color_coe_g0[7:0]  <= I_bus_wdata[7:0];
            //8'h0b : O_cfg_color_coe_g0[15:8] <= I_bus_wdata[7:0];
            //8'h0c : O_cfg_color_coe_b0[7:0]  <= I_bus_wdata[7:0];
            //8'h0d : O_cfg_color_coe_b0[15:8] <= I_bus_wdata[7:0];
            //8'h0e : O_cfg_color_coe_r1[7:0]  <= I_bus_wdata[7:0];
            //8'h0f : O_cfg_color_coe_r1[15:8] <= I_bus_wdata[7:0];
            //8'h10 : O_cfg_color_coe_g1[7:0]  <= I_bus_wdata[7:0];
            //8'h11 : O_cfg_color_coe_g1[15:8] <= I_bus_wdata[7:0];
            //8'h12 : O_cfg_color_coe_b1[7:0]  <= I_bus_wdata[7:0];
            //8'h13 : O_cfg_color_coe_b1[15:8] <= I_bus_wdata[7:0];
            //8'h14 : O_cfg_color_coe_r2[7:0]  <= I_bus_wdata[7:0];
            //8'h15 : O_cfg_color_coe_r2[15:8] <= I_bus_wdata[7:0];
            //8'h16 : O_cfg_color_coe_g2[7:0]  <= I_bus_wdata[7:0];
            //8'h17 : O_cfg_color_coe_g2[15:8] <= I_bus_wdata[7:0];
            //8'h18 : O_cfg_color_coe_b2[7:0]  <= I_bus_wdata[7:0];
            //8'h19 : O_cfg_color_coe_b2[15:8] <= I_bus_wdata[7:0];
            8'h1a : O_cfg_black_on_lost      <= I_bus_wdata[0];
        endcase
    end
    else if (I_bus_write && I_bus_addr[15:8] == 8'h90) begin
        case (I_bus_addr[7:0])
            8'h00 : O_cfg_pixel_adj_en       <= (I_bus_wdata == 8'h01);
            8'h01 : O_cfg_pixel_adj_mode     <= I_bus_wdata[0];
        endcase
    end
    else if (I_bus_write && I_bus_addr[15:8] == 8'ha0) begin
        case (I_bus_addr[7:0])
            8'h00 : O_cfg_pwm_setting[7:0]     <= I_bus_wdata;
            8'h01 : O_cfg_pwm_setting[15:8]    <= I_bus_wdata;
            8'h02 : O_cfg_pwm_setting[23:16]   <= I_bus_wdata;
            8'h03 : O_cfg_pwm_setting[31:24]   <= I_bus_wdata;
            8'h04 : O_cfg_pwm_setting[39:32]   <= I_bus_wdata;
            8'h05 : O_cfg_pwm_setting[47:40]   <= I_bus_wdata;
            8'h06 : O_cfg_pwm_setting[55:48]   <= I_bus_wdata;
            8'h07 : O_cfg_pwm_setting[63:56]   <= I_bus_wdata;
            8'h08 : O_cfg_pwm_setting[71:64]   <= I_bus_wdata;
            8'h09 : O_cfg_pwm_setting[79:72]   <= I_bus_wdata;
            8'h0a : O_cfg_pwm_setting[87:80]   <= I_bus_wdata;
            8'h0b : O_cfg_pwm_setting[95:88]   <= I_bus_wdata;
            8'h0c : O_cfg_pwm_setting[103:96]  <= I_bus_wdata;
            8'h0d : O_cfg_pwm_setting[111:104] <= I_bus_wdata;
            8'h0e : O_cfg_pwm_setting[119:112] <= I_bus_wdata;
            8'h0f : O_cfg_pwm_setting[127:120] <= I_bus_wdata;
            8'h10 : O_cfg_pwm_setting[135:128] <= I_bus_wdata;
            8'h11 : O_cfg_pwm_setting[143:136] <= I_bus_wdata;
            8'h12 : O_cfg_pwm_setting[151:144] <= I_bus_wdata;
            8'h13 : O_cfg_pwm_setting[159:152] <= I_bus_wdata;
            8'h14 : O_cfg_pwm_setting[167:160] <= I_bus_wdata;
            8'h15 : O_cfg_pwm_setting[175:168] <= I_bus_wdata;
            8'h16 : O_cfg_pwm_setting[183:176] <= I_bus_wdata;
            8'h17 : O_cfg_pwm_setting[191:184] <= I_bus_wdata;
            8'h18 : O_cfg_pwm_setting[199:192] <= I_bus_wdata;
            8'h19 : O_cfg_pwm_setting[207:200] <= I_bus_wdata;
            8'h1a : O_cfg_pwm_setting[215:208] <= I_bus_wdata;
            8'h1b : O_cfg_pwm_setting[223:216] <= I_bus_wdata;
            8'h1c : O_cfg_pwm_setting[231:224] <= I_bus_wdata;
            8'h1d : O_cfg_pwm_setting[239:232] <= I_bus_wdata;
            8'h1e : O_cfg_pwm_setting[247:240] <= I_bus_wdata;
            8'h1f : O_cfg_pwm_setting[255:248] <= I_bus_wdata;
        endcase
    end
    else if (I_bus_write && I_bus_addr[15:8] == 8'h01) begin
        case (I_bus_addr[7:0])
            8'h00 : O_cfg_gap_adj_en           <= (I_bus_wdata == 8'h01);
            8'h01 : O_cfg_module_width         <= I_bus_wdata;
            8'h02 : O_cfg_module_height        <= I_bus_wdata;
            8'h03 : O_cfg_module_col           <= I_bus_wdata[5:0];
            8'h04 : O_cfg_gap_center[7:0]      <= I_bus_wdata;
            8'h05 : O_cfg_gap_center[15:8]     <= I_bus_wdata;
        endcase
    end
    else if (I_bus_write && I_bus_addr[15:8] == 8'hf0 && I_bus_init_done) begin
        case (I_bus_addr[7:0])
            8'h02 : O_cfg_pattern_mode         <= I_bus_wdata[3:0];
            8'h03 : O_cfg_pattern_rgb          <= I_bus_wdata[2:0];
            8'h04 : O_cfg_pattern_col          <= I_bus_wdata[7:0];
            8'h05 : O_cfg_pattern_row          <= I_bus_wdata[7:0];
            8'h06 : O_cfg_pattern_pos_x        <= I_bus_wdata[7:0];
            8'h07 : O_cfg_gamma_enable         <= I_bus_wdata[0];
            8'h08 : O_cfg_pattern_width[7:0]   <= I_bus_wdata[7:0];
            8'h09 : O_cfg_pattern_width[10:8]  <= I_bus_wdata[2:0];
            8'h0a : O_cfg_pattern_height[7:0]  <= I_bus_wdata[7:0];
            8'h0b : O_cfg_pattern_height[10:8] <= I_bus_wdata[2:0];
            8'h0c : O_cfg_pattern_hblank[7:0]  <= I_bus_wdata[7:0];
            8'h0d : O_cfg_pattern_hblank[10:8] <= I_bus_wdata[2:0];
            8'h0e : O_cfg_pattern_vblank[7:0]  <= I_bus_wdata[7:0];
            8'h0f : O_cfg_pattern_vblank[10:8] <= I_bus_wdata[2:0];
            8'h10 : O_cfg_force_en             <= I_bus_wdata[0];
            8'h11 : O_cfg_force_bit            <= I_bus_wdata[4:0];
        endcase
    end
end

always @(posedge I_sclk or negedge I_rst_n) begin
    if (!I_rst_n) begin
        O_cfg_input_enable  <= 1'b0;
        O_cfg_output_enable <= 1'b0;
    end
    else if (!I_bus_init_done) begin
        O_cfg_input_enable  <= 1'b0;
        O_cfg_output_enable <= 1'b0;
    end
    else if (!init_done_sr && I_bus_init_done) begin
        O_cfg_input_enable  <= 1'b1;
        O_cfg_output_enable <= 1'b1;
    end
    else if (I_bus_write && I_bus_addr[15:8] == 8'hf0 && I_bus_init_done) begin
        case (I_bus_addr[7:0])
            8'h00 : O_cfg_input_enable  <= I_bus_wdata[0];
            8'h01 : O_cfg_output_enable <= I_bus_wdata[0];
        endcase
    end
end

// init_done_sr
always @(posedge I_sclk or negedge I_rst_n) begin
    if (!I_rst_n)
        init_done_sr <= 1'b1;
    else
        init_done_sr <= I_bus_init_done;
end
//}}}++++++++++++++++++++++++++++++++++++++++++++++++++++

//{{{+++++++++++++++++++++ram0+++++++++++++++++++++++++++
assign ram0_wren  = I_bus_write && I_bus_addr[15:10] == {4'h7, 2'h0}; // 0x7000
assign ram0_waddr = I_bus_addr[9:0];
assign ram0_data  = I_bus_wdata;
//}}}++++++++++++++++++++++++++++++++++++++++++++++++++++

//{{{+++++++++++++++++++++ram1+++++++++++++++++++++++++++
assign ram1_wren  = I_bus_write && I_bus_addr[15:10] == {4'h6, 2'h1}; // 0x6400
assign ram1_waddr = I_bus_addr[9:0];
assign ram1_data  = I_bus_wdata;
assign ram1_rden  = I_cycle_info_rden;
assign ram1_raddr = I_cycle_info_addr;

assign O_cycle_info_q  = ram1_q;
//}}}++++++++++++++++++++++++++++++++++++++++++++++++++++

//{{{+++++++++++++++++++++ram2+++++++++++++++++++++++++++
assign ram2_wren  = I_bus_write && I_bus_addr[15:10] == {4'h4, 2'h0}; // 0x4000
assign ram2_waddr = I_bus_addr[9:0];
assign ram2_data  = I_bus_wdata;
assign ram2_rden  = I_col_addr_req;
assign ram2_raddr = I_col_addr_index;

assign O_col_addr_data = ram2_q[8:0];
//}}}++++++++++++++++++++++++++++++++++++++++++++++++++++

//{{{+++++++++++++++++++++ram3+++++++++++++++++++++++++++
assign ram3_wren_a = I_bus_write && I_bus_addr[15:10] == {4'h5, 2'h0}; // 0x5000
assign ram3_rden_a = ~ram3_wren_a & row_info_req;
assign ram3_be_a   = I_bus_addr[0]? 2'b10 : 2'b01;
assign ram3_addr_a = ~ram3_wren_a? {1'b0, row_info_index} : I_bus_addr[9:1];
assign ram3_data_a = {I_bus_wdata, I_bus_wdata};
assign ram3_wren_b = 1'b0;
assign ram3_rden_b = I_scan_map_rden;
assign ram3_addr_b = {1'b1, 2'b0, I_scan_map_addr};
assign ram3_data_b = 1'b0;

assign row_info_data = ram3_q_a;
assign O_scan_map_q  = ram3_q_b[5:0];
//}}}++++++++++++++++++++++++++++++++++++++++++++++++++++

//{{{+++++++++++++++++++++ram4+++++++++++++++++++++++++++
assign ram4_wren    = I_bus_write && I_bus_addr[15:10] == {4'h3, 2'h0}; // 0x3000
assign ram4_waddr   = I_bus_addr[9:0];
assign ram4_data    = I_bus_wdata;
assign ram4_rden    = I_port_map_rden;
assign ram4_raddr   = I_port_map_addr;
assign O_port_map_q = ram4_q[4:0];
//}}}++++++++++++++++++++++++++++++++++++++++++++++++++++

//{{{+++++++++++++++++++++ram4_2+++++++++++++++++++++++++
assign ram4_wren_2    = I_bus_write && I_bus_addr[15:10] == {4'h3, 2'h1}; // 0x3400
assign ram4_waddr_2   = I_bus_addr[9:0];
assign ram4_data_2    = I_bus_wdata;
assign ram4_rden_2    = I_port_map_rden_2;
assign ram4_raddr_2   = I_port_map_addr_2;
assign O_port_map_q_2 = ram4_q_2[15:0];
//}}}++++++++++++++++++++++++++++++++++++++++++++++++++++

//{{{+++++++++++++++++++++ram5+++++++++++++++++++++++++++
assign ram5_wren  = I_bus_write && I_bus_addr[15:10] == {4'h0, 2'h1}; // 0x0400
assign ram5_waddr = I_bus_addr[9:0];
assign ram5_data  = I_bus_wdata;
//}}}++++++++++++++++++++++++++++++++++++++++++++++++++++

//{{{+++++++++++++++++++++other++++++++++++++++++++++++++
assign O_bus_rdata = 1'b0;
//}}}++++++++++++++++++++++++++++++++++++++++++++++++++++

endmodule

`default_nettype wire

// vim:set ts=4 sw=4 et fenc=utf-8 fdm=marker:
